/*!
 * \file BoostFile.hpp
 * \project	WonderTrader
 *
 * \author Wesley
 * \date 2020/03/30
 * 
 * \brief 基于boost::interprocess的文件操作封装类
 * 
 * \details 提供高性能的文件操作功能，包括：
 *          - 跨平台文件创建、打开、读写操作
 *          - 文件指针定位和大小获取
 *          - 目录创建和文件存在性检查
 *          - 静态工具函数支持
 *          
 *          基于boost::interprocess实现，提供比标准库更高效的
 *          文件操作性能，特别适用于大文件和高频文件操作场景。
 */
#pragma once
#include <boost/version.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/filesystem.hpp>
#include <boost/interprocess/detail/os_file_functions.hpp>
#include <string>

#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#else
#include <unistd.h>
#endif

//struct OVERLAPPED;
//extern "C" __declspec(dllimport) int __stdcall ReadFile(void *hnd, void *buffer, unsigned long bytes_to_write,unsigned long *bytes_written, OVERLAPPED* overlapped);

/*!
 * \brief Boost文件操作封装类
 * 
 * \details 基于boost::interprocess提供高性能文件操作，特点：
 *          - 跨平台文件句柄管理
 *          - 高效的文件读写操作
 *          - 完整的文件定位和大小控制
 *          - 异常安全的资源管理
 *          - 静态工具函数支持
 *          
 *          适用于需要高性能文件操作的场景，如数据存储、
 *          日志记录、配置文件处理等。
 */
class BoostFile
{
public:
	/// 构造函数，初始化为无效文件句柄
	BoostFile()
	{
		_handle=boost::interprocess::ipcdetail::invalid_file(); 
	}
	
	/// 析构函数，自动关闭文件
	~BoostFile()
	{
		close_file();
	}

	/*!
	 * \brief 创建新文件
	 * \param name 文件名
	 * \param mode 文件访问模式，默认读写模式
	 * \param temporary 是否为临时文件，默认false
	 * \return 成功返回true，失败返回false
	 * \note 如果文件已存在会截断为0字节
	 */
	bool create_new_file(const char *name, boost::interprocess::mode_t mode = boost::interprocess::read_write, bool temporary = false)
	{
		_handle=boost::interprocess::ipcdetail::create_or_open_file(name,mode,boost::interprocess::permissions(),temporary);

		if (valid())
			return truncate_file(0);
		return false;
	}

	/*!
	 * \brief 创建或打开文件
	 * \param name 文件名
	 * \param mode 文件访问模式，默认读写模式
	 * \param temporary 是否为临时文件，默认false
	 * \return 成功返回true，失败返回false
	 * \note 如果文件不存在会创建，存在则直接打开
	 */
	bool create_or_open_file(const char *name, boost::interprocess::mode_t mode = boost::interprocess::read_write, bool temporary = false)
	{
		_handle=boost::interprocess::ipcdetail::create_or_open_file(name,mode,boost::interprocess::permissions(),temporary);

		return valid();
	}

	/*!
	 * \brief 打开已存在的文件
	 * \param name 文件名
	 * \param mode 文件访问模式，默认读写模式
	 * \param temporary 是否为临时文件，默认false
	 * \return 成功返回true，失败返回false
	 * \note 文件必须已存在，否则打开失败
	 */
	bool open_existing_file(const char *name, boost::interprocess::mode_t mode = boost::interprocess::read_write, bool temporary = false)
	{
		_handle=boost::interprocess::ipcdetail::open_existing_file(name,mode,temporary);
		return valid();
	}

	/*!
	 * \brief 检查文件句柄是否无效
	 * \return 无效返回true，有效返回false
	 */
	bool is_invalid_file()
	{  
		return _handle==boost::interprocess::ipcdetail::invalid_file();  
	}

	/*!
	 * \brief 检查文件句柄是否有效
	 * \return 有效返回true，无效返回false
	 */
	bool valid()
	{
		return _handle!=boost::interprocess::ipcdetail::invalid_file();
	}

	/// 关闭文件，释放资源
	void close_file()
	{
		if(!is_invalid_file())
		{
			boost::interprocess::ipcdetail::close_file(_handle);
			_handle=boost::interprocess::ipcdetail::invalid_file();
		}
	}

	/*!
	 * \brief 截断文件到指定大小
	 * \param size 目标文件大小
	 * \return 成功返回true，失败返回false
	 */
	bool truncate_file (std::size_t size)
	{
		return boost::interprocess::ipcdetail::truncate_file(_handle,size);
	}

	/*!
	 * \brief 获取文件大小
	 * \param size 输出参数，文件大小
	 * \return 成功返回true，失败返回false
	 */
	bool get_file_size(boost::interprocess::offset_t &size)
	{
		return boost::interprocess::ipcdetail::get_file_size(_handle,size);
	}

	/*!
	 * \brief 获取文件大小
	 * \return 文件大小，失败返回0
	 */
	unsigned long long get_file_size()
	{
		boost::interprocess::offset_t size=0;
		if(!get_file_size(size))
			size=0;
		return size;
	}

	/*!
	 * \brief 静态方法：获取指定文件的大小
	 * \param name 文件名
	 * \return 文件大小，失败返回0
	 */
	static unsigned long long get_file_size(const char *name)
	{
		BoostFile bf;
		if (!bf.open_existing_file(name))
			return 0;

		auto ret = bf.get_file_size();
		bf.close_file();
		return ret;
	}

	/*!
	 * \brief 设置文件指针位置
	 * \param off 偏移量
	 * \param pos 起始位置（文件开头、当前位置、文件末尾）
	 * \return 成功返回true，失败返回false
	 */
	bool set_file_pointer(boost::interprocess::offset_t off, boost::interprocess::file_pos_t pos)
	{
		return boost::interprocess::ipcdetail::set_file_pointer(_handle,off,pos);
	}

	/*!
	 * \brief 定位到文件开头
	 * \param offsize 相对偏移量，默认0
	 * \return 成功返回true，失败返回false
	 */
	bool seek_to_begin(int offsize=0)
	{
		return set_file_pointer(offsize,boost::interprocess::file_begin);
	}

	/*!
	 * \brief 从当前位置偏移
	 * \param offsize 偏移量，默认0
	 * \return 成功返回true，失败返回false
	 */
	bool seek_current(int offsize=0)
	{
		return set_file_pointer(offsize,boost::interprocess::file_current);
	}

	/*!
	 * \brief 定位到文件末尾
	 * \param offsize 相对偏移量，默认0
	 * \return 成功返回true，失败返回false
	 */
	bool seek_to_end(int offsize=0)
	{
		return set_file_pointer(offsize,boost::interprocess::file_end);
	}

	/*!
	 * \brief 获取当前文件指针位置
	 * \param off 输出参数，当前位置
	 * \return 成功返回true，失败返回false
	 */
	bool get_file_pointer(boost::interprocess::offset_t &off)
	{
		return boost::interprocess::ipcdetail::get_file_pointer(_handle,off);
	}

	/*!
	 * \brief 获取当前文件指针位置
	 * \return 当前位置，失败返回0
	 */
	unsigned long long get_file_pointer()
	{
		boost::interprocess::offset_t off=0;
		if(!get_file_pointer(off))
			return 0;
		return off;
	}

	/*!
	 * \brief 写入数据到文件
	 * \param data 数据指针
	 * \param numdata 数据大小
	 * \return 成功返回true，失败返回false
	 */
	bool write_file(const void *data, std::size_t numdata)
	{
		return boost::interprocess::ipcdetail::write_file(_handle,data,numdata);
	}

	/*!
	 * \brief 写入字符串到文件
	 * \param data 字符串数据
	 * \return 成功返回true，失败返回false
	 */
	bool write_file(const std::string& data)
	{
		return boost::interprocess::ipcdetail::write_file(_handle, data.data(), data.size());
	}

	/*!
	 * \brief 从文件读取数据
	 * \param data 数据缓冲区
	 * \param numdata 要读取的字节数
	 * \return 成功返回true（读取完整数据），失败返回false
	 */
	bool read_file(void *data, std::size_t numdata)
	{
		unsigned long readbytes = 0;
#ifdef _WIN32
		int ret = ReadFile(_handle, data, (DWORD)numdata, &readbytes, NULL);
#else
		readbytes = read(_handle, data, (std::size_t)numdata);
#endif
		return numdata == readbytes;
	}

	/*!
	 * \brief 从文件读取数据并返回实际读取长度
	 * \param data 数据缓冲区
	 * \param numdata 要读取的字节数
	 * \return 实际读取的字节数
	 */
	int read_file_length(void *data, std::size_t numdata)
	{
		unsigned long readbytes = 0;
#ifdef _WIN32
		int ret = ReadFile(_handle, data, (DWORD)numdata, &readbytes, NULL);
#else
		readbytes = read(_handle, data, (std::size_t)numdata);
#endif
		return readbytes;
	}

private:
	boost::interprocess::file_handle_t _handle;	///< 文件句柄

public:
	/*!
	 * \brief 静态方法：删除文件
	 * \param name 文件名
	 * \return 成功返回true，失败返回false
	 */
	static bool delete_file(const char *name)
	{
		return boost::interprocess::ipcdetail::delete_file(name);
	}

	/*!
	 * \brief 静态方法：读取文件全部内容到字符串
	 * \param filename 文件名
	 * \param buffer 输出缓冲区
	 * \return 成功返回true，失败返回false
	 */
	static bool read_file_contents(const char *filename,std::string &buffer)
	{
		BoostFile bf;
		if(!bf.open_existing_file(filename,boost::interprocess::read_only))
			return false;
		unsigned int filesize=(unsigned int)bf.get_file_size();
		if(filesize==0)
			return false;
		buffer.resize(filesize);
		return bf.read_file((void *)buffer.c_str(),filesize);
	}

	/*!
	 * \brief 静态方法：写入数据到文件
	 * \param filename 文件名
	 * \param pdata 数据指针
	 * \param datalen 数据长度
	 * \return 成功返回true，失败返回false
	 */
	static bool write_file_contents(const char *filename,const void *pdata,uint32_t datalen)
	{
		BoostFile bf;
		if(!bf.create_new_file(filename))
			return false;
		return bf.write_file(pdata,datalen);
	}

	/*!
	 * \brief 静态方法：创建目录
	 * \param name 目录名
	 * \return 成功返回true，失败返回false
	 * \note 如果目录已存在，直接返回true
	 */
	static bool create_directory(const char *name)
	{
		if(exists(name))
			return true;

		return boost::filesystem::create_directory(boost::filesystem::path(name));
	}

	/*!
	 * \brief 静态方法：创建多级目录
	 * \param name 目录路径
	 * \return 成功返回true，失败返回false
	 * \note 会递归创建所有不存在的父目录
	 */
	static bool create_directories(const char *name)
	{
		if(exists(name))
			return true;

		return boost::filesystem::create_directories(boost::filesystem::path(name));
	}

	/*!
	 * \brief 静态方法：检查文件或目录是否存在
	 * \param name 文件或目录名
	 * \return 存在返回true，不存在返回false
	 */
	static bool exists(const char* name)
	{
		return boost::filesystem::exists(boost::filesystem::path(name));
	}
};

/// BoostFile智能指针类型定义
typedef boost::shared_ptr<BoostFile> BoostFilePtr;